class Transaction {
	constructor(wrapper) {
		this.wrapper = wrapper
	}
	perform(func) {
		this.wrapper.initialize()
		func.call()
		this.wrapper.close()
	}
}
// 批量处理
let batchingStrategy = {
	isBatchingUpdates: false,
	updaters: [],
	batchedUpdates() {
		this.updaters.forEach((updater) => {
			updater.component.updateComponent()
		})
	},
}
class Updater {
	constructor(component) {
		this.component = component
		this.pendingStates = []
	}
	addState(particalState) {
		this.pendingStates.push(particalState)
		batchingStrategy.isBatchingUpdates ? batchingStrategy.updaters.push(this) : this.component.updateComponent()
	}
}
let transaction = new Transaction({
	initialize() {
		batchingStrategy.isBatchingUpdates = true
	},
	close() {
		batchingStrategy.isBatchingUpdates = false
		batchingStrategy.batchedUpdates()
	},
})
window.trigger = function (event, name) {
	let component = event.target.component
	console.log(component)
	transaction.perform(component[name].bind(component, event))
}
class Component {
	constructor(props) {
		this.props = props
		this.$updater = new Updater(this)
	}
	createDOMFromString(domString) {
		const div = document.createElement('div')
		div.innerHTML = domString
		return div.children[0]
	}
	setState(particalState) {
		this.$updater.addState(particalState)
	}
	updateComponent() {
		let pendingStates = this.$updater.pendingStates
		pendingStates.forEach((particalState) => Object.assign(this.state, particalState))
		this.$updater.pendingStates.length = 0
		let oldElement = this.domElement
		let newElement = this.renderElement()
		oldElement.parentElement.replaceChild(newElement, oldElement)
	}
	renderElement() {
		let renderString = this.render()
		this.domElement = this.createDOMFromString(renderString)
		this.domElement.component = this
		return this.domElement
	}
	mount(container) {
		container.appendChild(this.renderElement())
	}
}
class Counter extends Component {
	constructor(props) {
		super(props)
		this.state = { number: 0 }
	}
	increment() {
		this.setState({ number: this.state.number + 1 })
		console.log(this.state)
		this.setState({ number: this.state.number + 1 })
		console.log(this.state)
		setTimeout(() => {
			this.setState({ number: this.state.number + 1 })
			console.log(this.state)
			this.setState({ number: this.state.number + 1 })
			console.log(this.state)
		}, 1000)
	}
	render() {
		return `
        <button id="counter-btn" onclick="trigger(event,'increment')">
         ${this.props.name}:${this.state.number}
        </button>
        `
	}
}
